package lumis.portal.presentation.perspective.admin;

import lumis.portal.PortalException;
import lumis.portal.PortalObjectNotFoundException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.channel.ChannelConfig;
import lumis.portal.localization.ILocalizationManager;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.page.PageConfig;
import lumis.portal.presentation.PageRendererUtil;
import lumis.portal.presentation.core.LayoutFilePage;
import lumis.portal.presentation.layout.defaultlayout.AbstractPageBodyMiddleComponent;
import lumis.portal.presentation.perspective.Perspective;
import lumis.portal.serviceinstance.ServiceInstanceConfig;
import lumis.portal.serviceinterface.IServiceInterfaceManager;
import lumis.portal.serviceinterface.ServiceInterfaceConfig;
import lumis.portal.serviceinterfaceinstance.IServiceInterfaceInstanceManager;
import lumis.portal.serviceinterfaceinstance.ServiceInterfaceInstanceConfig;
import lumis.portal.transaction.PortalTransactionFactory;
import lumis.util.ITransaction;
import lumis.util.XmlUtil;

import java.util.Locale;

import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * Injects the components HTML for portal studio
 * @version $Revision: 13321 $ $Date: 2011-08-08 11:32:13 -0300 (Mon, 08 Aug 2011) $
 * @since 6.0.0
 */
@SuppressWarnings("serial")
public class PortalStudioBodyMiddleComponent extends AbstractPageBodyMiddleComponent 
{
	/**
	 * Constructor for the class.
	 * @param id component identifier
	 * @since 6.0.0
	 */
	public PortalStudioBodyMiddleComponent(String id) 
	{
		super(id);
	}
	
	@Override
	public CharSequence getHTMLFragment(MarkupStream markupStream, ComponentTag openTag) 
	{
		try
		{
			AppendingStringBuffer result = new AppendingStringBuffer(15000);
			
			ITransaction portalTransaction = PortalTransactionFactory.getCurrentTransaction();
			LayoutFilePage page = ((LayoutFilePage)getPage());
			SessionConfig sessionConfig = SessionConfig.getCurrentSessionConfig();
			PageConfig pageConfig = page.getPageWebResource().getPage();
			ChannelConfig channelConfig = ManagerFactory.getChannelManager().get(sessionConfig, pageConfig.getChannelId(), portalTransaction);
			String rootChannelId = page.getRootChannelId();
			
			Document pageLayout = getPageLayout();
		
			ILocalizationManager localizationManager = ManagerFactory.getLocalizationManager();
			IServiceInterfaceInstanceManager serviceInterfaceInstanceManager = ManagerFactory.getServiceInterfaceInstanceManager();
			Locale locale = sessionConfig.getLocale();
		
			boolean allowLayoutPropertiesModification = (pageConfig.isTemplate() || pageConfig.getParentTemplateId() == null);
		
			Node[] areas = XmlUtil.selectNodes("layout/area", pageLayout);
			int columnInputIndex=1;
			for (int i = 0; i < areas.length; i++)
			{
				Node[] columns = XmlUtil.selectNodes("column", areas[i]);
		
				boolean columnsHavePercentWidths = columnsHavePercentWidths(columns);
		
				String areaClassName = XmlUtil.readAttributeString("className", areas[i], "");
		
				result.append("<table");
		
				if (!rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
					result.append(" layoutId=\"" + i + "\" name=\"LumisArea\" id=\"LumisArea_"+i+"\"");
		
				if (areaClassName.length() > 0)
					result.append(" class=\"" + areaClassName + "\"");
		
				if (columnsHavePercentWidths)
					result.append(" style=\"width:100%\"");
		
				result.append(" cellpadding=\"0\" cellspacing=\"0\"><tr>");
		
				// if in admin mode render the area administration
				if (!rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
				{
					String areaPropertiesScript = "var pLumisArea=g_LumisPage.getElement(\\'LumisArea\\', \\'" + i + "\\');g_LumisContextMenu.hide();if(LumisPortalAdmin.inEditMode && " + allowLayoutPropertiesModification + "){g_LumisPage.callLayoutElementProperties(\\'LumisArea\\', \\'" + i + "\\', pLumisArea.className, \\'" + channelConfig.getId() + "\\');}else{g_LumisPage.callLayoutElementPropertiesReadOnly(pLumisArea.className, \\'" + channelConfig.getId() + "\\');};";
		
					result.append("<td id=\"LumisAreaAdmin\" name=\"LumisAreaAdmin\" class=\"cLumAreaAdmin\" style=\"display:none\" oncontextmenu=\"g_LumisContextMenu.show(this, g_LumisContextMenu.generateHeader('STR_AREA_PROPERTIES')+g_LumisContextMenu.generateMenuItem('STR_PROPERTIES', '" + areaPropertiesScript + "', false)+g_LumisContextMenu.generateFooter(), window.event.x, window.event.y);event.returnValue = false;event.cancelBubble = true;\">");
		
					if (pageConfig.getParentTemplateId() == null)
					{
						result.append("<div><img src=\"lumis/portal/client/images/AddAreaAbove.gif\" title=\"");
						result.append(localizationManager.localize("STR_ADD_AREA_ABOVE", PortalAdminStringResource.getInstance(), sessionConfig.getLocale()));
						result.append("\" onclick=\"g_LumisPage.onAddArea(0, 'LumisArea_"+i+"');\" alt=\" \"/></div>");
						result.append("<div><img src=\"lumis/portal/client/images/DeleteArea.gif\" title=\"");
						result.append(localizationManager.localize("STR_DELETE_AREA", PortalAdminStringResource.getInstance(), sessionConfig.getLocale()));
						result.append("\" onclick=\"g_LumisPage.onDeleteArea('LumisArea_"+i+"');\" alt=\" \" /></div>");
						result.append("<div><img src=\"lumis/portal/client/images/AddAreaBelow.gif\" title=\"");
						result.append(localizationManager.localize("STR_ADD_AREA_BELOW", PortalAdminStringResource.getInstance(), sessionConfig.getLocale()));
						result.append("\" onclick=\"g_LumisPage.onAddArea(1, 'LumisArea_"+i+"');\" alt=\" \" /></div>");
					}
					else
					{
						result.append("<div style=\"width:10px\"></div>");
					}
		
					result.append("</td>");
				}
		
				for (int j = 0; j < columns.length; j++)
				{
					Node curColumn = columns[j];
					Node[] rows = XmlUtil.selectNodes("row", curColumn);
		
					String columnWidth = XmlUtil.readAttributeString("width", curColumn);
					String columnClassName = XmlUtil.readAttributeString("className", curColumn, "");
		
					result.append("<td valign=\"top\"");
		
					if (!rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
						result.append(" layoutId=\"" + i + "_" + j + "\" id=\"LumisColumn\" name=\"LumisColumn\"");
		
					if (columnClassName.length() > 0)
						result.append(" class=\"" + columnClassName + "\"");
		
					if (columnWidth != null)
					{
						if(columnWidth.contains("%"))
							result.append(" style=\"width:" + columnWidth + ";\"");
						else
							result.append(" style=\"width:" + columnWidth + "px;\"");
					}
		
					result.append(">");
		
					if (!rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
					{
						String columnPropertiesScript = "var pLumisColumn=g_LumisPage.getElement(\\'LumisColumn\\', \\'" + i + "_" + j + "\\');g_LumisContextMenu.hide();if(LumisPortalAdmin.inEditMode && " + allowLayoutPropertiesModification + "){g_LumisPage.callLayoutElementProperties(\\'LumisColumn\\', \\'" + i + "_" + j + "\\', pLumisColumn.className, \\'" + channelConfig.getId() + "\\');}else{g_LumisPage.callLayoutElementPropertiesReadOnly(pLumisColumn.className, \\'" + channelConfig.getId()
								+ "\\');};";
		
						result.append("<div name=\"LumisColumnSizer\" id=\"LumisColumnSizer\" class=\"cLumColumnSizer\" oncontextmenu=\"g_LumisContextMenu.show(this, g_LumisContextMenu.generateHeader('STR_COLUMN_PROPERTIES')+g_LumisContextMenu.generateMenuItem('STR_PROPERTIES', '" + columnPropertiesScript + "', false)+g_LumisContextMenu.generateFooter(), window.event.x, window.event.y);event.returnValue = false;event.cancelBubble = true;\" style=\"display:none; white-space: nowrap; text-align: center");
						if (columnWidth != null)
						{
							if (columnWidth.indexOf("%") > -1)
							{
								result.append(";width:100%");
							}
							else
							{
								result.append(";width:");
								result.append(columnWidth);
		
								if(!columnWidth.contains("%"))
									result.append("px");
		
								result.append(";");
							}
						}
						result.append("\">");
						
						String columnSizerInputId = "LumisColumnSizerInput"+columnInputIndex;
						columnInputIndex++;
						
						if (pageConfig.getParentTemplateId() == null)
						{
							result.append("<img id=\"lumDeleteColumnButton\" src=\"lumis/portal/client/images/DeleteColumn.gif\" onclick=\"g_LumisPage.onDeleteColumn('"+columnSizerInputId+"')\" style=\"margin: 6px 0px; float: right;\" alt=\" \" />");
							result.append("<img src=\"lumis/portal/client/images/LeftArrow.gif\" style=\"vertical-align: middle;\" onclick=\"g_LumisPage.onColSizeChange(-1, document.getElementById('"+columnSizerInputId+"'))\" ondblclick=\"g_LumisPage.onColSizeChange(-9, document.getElementById('"+columnSizerInputId+"'))\" alt=\" \" />");
						}
		
						result.append("<input name=\"LumisColumnSizerInput\" id=\""+columnSizerInputId+"\" type=\"text\" size=\"5\"");
		
						if (pageConfig.getParentTemplateId() == null)
						{
							result.append(" onchange=\"g_LumisPage.onColSizeChange(0, document.getElementById('"+columnSizerInputId+"'))\" onblur=\"g_LumisPage.onColSizeChange(0, document.getElementById('"+columnSizerInputId+"'))\" onkeypress=\"if(window.event && window.event.keyCode == 13)g_LumisPage.onColSizeChange(0, document.getElementById('"+columnSizerInputId+"'))\" ");
						}
						else
						{
							result.append(" readonly=\"readonly\" ");
						}
		
						if (columnWidth != null)
						{
							result.append("value=\"");
							result.append(columnWidth);
							result.append("\"");
						}
						result.append("/>");
		
						if (pageConfig.getParentTemplateId() == null)
						{
							result.append("<img src=\"lumis/portal/client/images/RightArrow.gif\" style=\"vertical-align: middle;\" onclick=\"g_LumisPage.onColSizeChange(1, document.getElementById('"+columnSizerInputId+"'))\" ondblclick=\"g_LumisPage.onColSizeChange(9, document.getElementById('"+columnSizerInputId+"'))\" alt=\" \" />");
						}
		
						result.append("&#160;&#160;&#160;</div>");
					}
		
					result.append("<table cellpadding=\"0\" cellspacing=\"0\" style=\"width:");
		
					if(columnWidth == null || columnWidth.contains("%"))
						result.append("100%");
					else
						result.append(columnWidth+"px");
					result.append("\">");
		
					boolean hasRows = false;
		
					for (int k = 0; k < rows.length; k++)
					{
						hasRows = true;
						result.append("<tr ");
						result.append("id=\"LumisRow\" name=\"LumisRow\" ");
						result.append("class=\"cLumisRow\">");
						Node[] cells = XmlUtil.selectNodes("cell", rows[k]);
		
						boolean hasCells = false;
						for (int l = 0; l < cells.length; l++)
						{
							String serviceInterfaceInstanceId = XmlUtil.getTextContent(cells[l]);
							ServiceInterfaceInstanceConfig serviceInterfaceInstanceConfig;
							try
							{
								serviceInterfaceInstanceConfig = ManagerFactory.getServiceInterfaceInstanceManager().get(sessionConfig, serviceInterfaceInstanceId, portalTransaction);
							}
							catch (PortalObjectNotFoundException e)
							{
								// eat this exception.
								continue;
							}
		
							if (serviceInterfaceInstanceConfig.getServiceInterfaceId().equals(IServiceInterfaceManager.INTERFACE_HOLDER_ID) && (rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID)))
								continue;

							if (serviceInterfaceInstanceConfig.getServiceInterfaceId().equals(
									IServiceInterfaceManager.INTERFACE_HOLDER_ID)
									&& !(Perspective.ADMIN.equals(page.getPortalMode()
											.getPerspective())))
								continue;
		
							ServiceInterfaceConfig serviceInterfaceConfig = ManagerFactory.getServiceInterfaceManager().getServiceInterfaceConfig(serviceInterfaceInstanceConfig.getServiceInterfaceId(), portalTransaction);
		
							if (page.isPrinting())
							{
								if (serviceInterfaceInstanceConfig.getPrintable() == ServiceInterfaceInstanceConfig.PRINT_INTERFACE_NO || (serviceInterfaceInstanceConfig.getPrintable() == ServiceInterfaceInstanceConfig.PRINT_INTERFACE_INHERIT && !serviceInterfaceConfig.isPrintable()))
									continue;
							}
		
							if (pageConfig.getType() != PageConfig.PAGE_TYPE_ADMIN && !rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
							{
								String serviceInstanceId = serviceInterfaceInstanceConfig.getServiceInstanceId();
								ServiceInstanceConfig serviceInstanceConfig = serviceInstanceId != null ? ManagerFactory
										.getServiceInstanceManager().get(serviceInstanceId, portalTransaction) : null;
		
								result.append("<td valign=\"top\" lumInterfaceInstId=\"");
								result.append(serviceInterfaceInstanceId);
								result.append("\" name=\"LumisInterface\" id=\"LumisInterface\" class=\"cLumisInterface\" lumInterfaceName=\"");
								String interfaceInstanceName = ManagerFactory.getServiceInterfaceInstanceManager().getDisplayName(serviceInterfaceInstanceConfig, portalTransaction);
								result.append(XmlUtil.encodeXml(localizationManager.localize(interfaceInstanceName, serviceInterfaceConfig.getResource(), locale)));
								result.append("\"");
		
								result.append(" lumServiceInstName=\"");
								if (serviceInstanceConfig != null)
									result.append(XmlUtil.encodeXml(localizationManager.localize(serviceInstanceConfig.getName(),
											serviceInterfaceConfig.getResource(), locale)));
								result.append("\"");
		
								result.append(" lumServiceInstId=\"");
								if (serviceInstanceConfig != null)
									result.append(XmlUtil.encodeXml(serviceInstanceConfig.getId()));
								result.append("\"");
		
		
								if (serviceInterfaceInstanceConfig.getServiceInterfaceId().equals(IServiceInterfaceManager.INTERFACE_HOLDER_ID))
									result.append(" isInterfaceHolder=\"1\" ");
								if (serviceInterfaceInstanceConfig.getParentInterfaceInstanceId() != null)
								{
									result.append(" isFromTemplate=\"1\" ");
									if (serviceInterfaceInstanceManager.getEnableCache(sessionConfig, serviceInterfaceInstanceConfig.getId(), portalTransaction))
										result.append(" cacheEnabled=\"1\" ");
								}
								else if (serviceInterfaceInstanceManager.getEnableCache(sessionConfig, serviceInterfaceInstanceId, portalTransaction))
								{
									result.append(" cacheEnabled=\"1\" ");
								}
		
								String strStyles = generateStyles(serviceInterfaceInstanceConfig);
								if (strStyles.length() > 0)
								{
									result.append("style=\"");
									result.append(strStyles);
									result.append("\"");
								}
		
								String strSpan = generateSpan(serviceInterfaceInstanceConfig);
								if (strSpan.length() > 0)
									result.append(strSpan);
		
								result.append("><div>");
							}
							else
							{
								result.append("<td valign=\"top\" class=\"cLumisInterface\" ");
								String strStyles = generateStyles(serviceInterfaceInstanceConfig);
		
								if (strStyles.length() > 0)
								{
									result.append("style=\"");
									result.append(strStyles);
									result.append("\"");
								}
		
								String strSpan = generateSpan(serviceInterfaceInstanceConfig);
								if (strSpan.length() > 0)
									result.append(strSpan);
								
								if(serviceInterfaceInstanceConfig.getId().equals(page.getHighlightInterfaceInst()))
									result.append(" id=\"H_"+page.getHighlightInterfaceInst()+"\"");
								result.append(">");
							}
		
							hasCells = true;
							
							result.append(PageRendererUtil.renderServiceInterfaceInstance(serviceInterfaceInstanceId, page));
		
							if (pageConfig.getType() != PageConfig.PAGE_TYPE_ADMIN && !rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
								result.append("</div>");
							result.append("</td>");
						}
						
						if(!hasCells)
							result.append("<td></td>");
						
						result.append("</tr>");
					}
		
					if (!hasRows)
					{
						result.append("<tr id=\"LumisRow\" name=\"LumisRow\" class=\"cLumisRow\"><td></td></tr>");
					}
		
					result.append("</table>");
					// if in admin mode render a div at the end of each colum to
					// represent the drop line
					if (Perspective.ADMIN.equals(page.getPortalMode().getPerspective()) && !rootChannelId.equals(ChannelConfig.LUMIS_ADMIN_CHANNEL_ID))
						result.append("<div class=\"cLumColumnDropLine\" style=\"display:none\"></div>");
					result.append("</td>");
				}
		
				result.append("</tr></table>");
			}

			return result;
		}
		catch (PortalException e)
		{
			throw new RuntimeException(e);
		}
	}
}
